/* Scheduler include files. */
#include <stdlib.h>
#include "FreeRTOS.h"
#include "myLCD.h"


void lcd_put_number(long num){			//Output a long number to LCD
	long num_temp=0;
	char no=0;
	if(num < 0){
		put_char_LCD(0x2D); // '-'
		num = -num;
	}
	while(num > 0){//convert 1230 -> 0321
		num_temp = num_temp*10 + num%10;
		num = num/10;
		no ++;
	}
	
	while(num_temp>0){
		put_char_LCD(num_temp%10 + 0x30);
		num_temp = num_temp/10;
		no --;
	}
	while(no >0){//fill zero
		put_char_LCD(0x30);
		no--;
	}
}

static char read2nib(void){
	char HNib, LNib;
	DATA_O |=0xF0;

    DDR_DATA &=0x0F;
	sbi(CTRL,EN); //enable
	sbi(CTRL,EN); // dong nay chi co tac dung delay vi chan EN da o muc cao roi
	

	HNib=DATA_I & 0xF0;
	cbi(CTRL,EN); //disable

	sbi(CTRL,EN); //enable
	sbi(CTRL,EN); //dong nay chi co tac dung delay vi chan EN da o muc cao roi	
	LNib = DATA_I & 0xF0;
	cbi(CTRL,EN); //disable
	LNib>>=4;
	return (HNib|LNib);
}

static void write2nib(uint8_t chr){

	uint8_t HNib, LNib, temp_data;	
	temp_data=DATA_O & 0x0F;

	HNib=chr & 0xF0;
	LNib=(chr<<4) & 0xF0;		
		
	DATA_O =(HNib |temp_data);	
	sbi(CTRL,EN); //enable
	cbi(CTRL,EN); //disable	
	
	DATA_O =(LNib|temp_data);		
	sbi(CTRL,EN); //enable
	cbi(CTRL,EN); //disable
}
#ifdef LCD8BIT
static void write8bit(uint8_t chr){
	DATA_O=chr;   //out 8 bits to DATA Line
	sbi(CTRL,EN); //enable
	cbi(CTRL,EN); //disable
}
#endif
void wait_LCD(void){	
	#ifdef LCD8BIT	
		while(1){
			cbi(CTRL,EN); //disable before doing sth
			cbi(CTRL,RS); //RS=0 mean the following data is COMMAND (not normal DATA)
			sbi(CTRL,RW); //the Direction of this COMMAND is from LCD -> chip
			
			DDR_DATA=0xFF;//Ready to Out
			DATA_O=0xFF; //Out the COMMAND, 0xFF means "Read Status Bit" COMMAND	
			sbi(CTRL,EN); //enable
			
			DDR_DATA=0x00;//Ready to IN
			if(bit_is_clear(DATA_I,7)) break;
		}
		cbi(CTRL,EN); //disable for next step	
		cbi(CTRL,RW); //ready for next step	
		DDR_DATA=0xFF;//Ready to Out
	#else
		char temp_val;
		while(1){
			cbi(CTRL,RS); //RS=0 mean the following data is COMMAND (not normal DATA)
			sbi(CTRL,RW); //the Direction of this COMMAND is from LCD -> chip
			temp_val=read2nib();
			if (bit_is_clear(temp_val,7)) break;
		}
		cbi(CTRL,RW); //ready for next step	
		DDR_DATA=0xFF;//Ready to Out		
	#endif
	
	//_delay_ms(1);
	
}


void init_LCD(void){
	DDR_CTRL=0xFF;
	DDR_DATA=0xFF;
//Function set------------------------------------------------------------------------------
	cbi(CTRL,RS);   // the following data is COMMAND
	cbi(CTRL, RW); // AVR->LCD
	cbi(CTRL, EN);
	#ifdef LCD8BIT	
		write8bit(0x38);
		wait_LCD();
	#else
		sbi(CTRL,EN); //enable
		sbi(DATA_O, 5); 
		cbi(CTRL,EN); //disable
		//wait_LCD();	
		_delay_ms(2);
		write2nib(0x28);//
		//wait_LCD();
		_delay_ms(2);
	#endif
//Display control-------------------------------------------------------------------------	
	cbi(CTRL,RS); // the following data is COMMAND 
	#ifdef LCD8BIT	
		write8bit(0x0E);
		wait_LCD();
	#else
		write2nib(0x0C);
		//wait_LCD();	
		_delay_ms(2);
	#endif
//Entry mode set------------------------------------------------------------------------
	cbi(CTRL,RS); // the following data is COMMAND 
	#ifdef LCD8BIT
		write8bit(0x06);
		wait_LCD();
	#else
		write2nib(0x06);
		//wait_LCD();
		_delay_ms(2);
	#endif
}

void home_LCD(void){
	cbi(CTRL,RS); // the following data is COMMAND 
	#ifdef LCD8BIT	
		write8bit(0x02);
		wait_LCD();	
	#else
		write2nib(0x02);
		//wait_LCD();
		_delay_ms(2);
	#endif	
}
void move_LCD(uint8_t x,uint8_t y){
	uint8_t Ad;
	Ad=64*(y)+(x)+0x80; //
	cbi(CTRL,RS); // the following data is COMMAND
	#ifdef LCD8BIT	
		write8bit(Ad);
		wait_LCD();
	#else
		write2nib(Ad);
		//wait_LCD();
		_delay_ms(2);
	#endif	
}

void clr_LCD(void){
	cbi(CTRL,RS); //RS=0 mean the following data is COMMAND (not normal DATA)
	#ifdef LCD8BIT	
		write8bit(0x01);
		wait_LCD();	
	#else
		write2nib(0x01);
		//wait_LCD();
		_delay_ms(2);
		
	#endif	
}

void put_char_LCD(uint8_t chr){
	sbi(CTRL,RS); //this is a normal DATA	
	#ifdef LCD8BIT	
		write8bit(chr);
		wait_LCD();	
	#else
		write2nib(chr);
		//wait_LCD();	
		_delay_ms(2);
	#endif		
}

void print_LCD(char* str){
	 unsigned char i;
	 for (i=0; str[i]!=0; i++) put_char_LCD(str[i]);	 
}